package cn.cxy.wanandroid.network

import android.net.ParseException
import cn.cxy.wanandroid.utils.OkHttpUrl.BASE_URL
import cn.cxy.wanandroid.utils.toast
import com.google.gson.GsonBuilder
import com.google.gson.JsonParseException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import org.json.JSONException
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

open class BaseRepository {

    val apiService: ApiService by lazy {
        val okHttpClient = OkHttpClient.Builder().build()
        Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
            .build().create(ApiService::class.java)
    }

    companion object {
        const val EXCEPTION_CODE_NOTWORK_ERROR = -10000
        const val EXCEPTION_CODE_NOTWORK_POOR = -10001
        const val EXCEPTION_CODE_PARSE_ERROR = -10002
        const val EXCEPTION_CODE_UNKNOWN_ERROR = -10003

        const val EXCEPTION_MSG_NOTWORK_ERROR = "网络错误"
        const val EXCEPTION_MSG_NOTWORK_POOR = "网络不给力"
        const val EXCEPTION_MSG_PARSE_ERROR = "解析错误"
        const val EXCEPTION_MSG_UNKNOWN_ERROR = "未知错误"
    }

    suspend fun <T> apiCall(call: suspend () -> BaseResponse<T>): BaseResponse<T> {
        return withContext(Dispatchers.IO) {
            try {
                call.invoke()
            } catch (e: Exception) {
                handleCallException<T>(e)
            }
        }

    }

    fun <T> handleCallException(e: Exception): BaseResponse<T> {
        var exceptionResponse: BaseResponse<T>?
        when (e) {
            is JSONException,
            is JsonParseException,
            is ParseException -> {
                exceptionResponse =
                    BaseResponse(EXCEPTION_CODE_PARSE_ERROR, EXCEPTION_MSG_PARSE_ERROR, null)
            }
            is ConnectException,
            is UnknownHostException -> {
                exceptionResponse =
                    BaseResponse(EXCEPTION_CODE_NOTWORK_ERROR, EXCEPTION_MSG_NOTWORK_ERROR, null)
            }
            is SocketTimeoutException -> {
                exceptionResponse =
                    BaseResponse(EXCEPTION_CODE_NOTWORK_POOR, EXCEPTION_MSG_NOTWORK_POOR, null)
            }
            else -> {
                exceptionResponse =
                    BaseResponse(EXCEPTION_CODE_UNKNOWN_ERROR, EXCEPTION_MSG_UNKNOWN_ERROR, null)
            }
        }

        if (exceptionResponse.errorMsg.isNotEmpty()) {
            toast(exceptionResponse.errorMsg)
        }

        return exceptionResponse
    }


}